package com.qf.jwt.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.qf.common.exception.BaseException;
import com.qf.common.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import java.util.Date;

/**
 * @author : sin
 * @date : 2024/1/14 17:03
 * @Description : jwt 工具类 生成和解析token
 */
@Component("JWTToken")
@Slf4j
public class JwtUtil {

    @Value("${token.secret}")
    private String SECRET;

    @Value("${token.expireTime}")
    private int EXPIRETIME;

    @Value("${token.time}")
    private int time;

    @Value("${token.prefix}")
    private String tokenPrefix;

    public String token(Authentication authentication) {
        return JWT.create()
                .withExpiresAt(new Date(System.currentTimeMillis() * 10000L + 100000L * 60 * EXPIRETIME))  //设置过期时间:单位毫秒
                .withAudience(JsonUtil.toJsonString(authentication)) //设置接受方信息，一般时登录用户
                .sign(Algorithm.HMAC256(SECRET));
    }

    public String refreshToken(Authentication authentication) {
        return JWT.create()
                .withExpiresAt(new Date(System.currentTimeMillis() * 10000L + 100000L * 60 * (EXPIRETIME + time)))  //设置过期时间:单位毫秒
                .withAudience(JsonUtil.toJsonString(authentication)) //设置接受方信息，一般时登录用户
                .sign(Algorithm.HMAC256(SECRET));
    }
    /**
     * 刷新token
     * @param token
     * @return
     */
    public String refreshToken(String token){
        tokenVerify(token);
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return token(authentication);
    }

    public void tokenVerify(String token) {

        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
            verifier.verify(token); // 没报错就说明验证成功
            JWT.decode(token).getExpiresAt();
            String json = JWT.decode(token).getAudience().get(0);
            JwtAuthentication jwtAuthentication = JSON.parseObject(json, JwtAuthentication.class);
            // TODO 从token中拿出来用户信息，设置到SecurityContextHolder中 后面需要修改，可以从redis中获取
            //  token 中存放username
            SecurityContextHolder.getContext().setAuthentication(jwtAuthentication);
        } catch (Exception e) {
            throw new BaseException(401,"token验证失败");
        }
    }
    public Long getExpriTime() {
        return System.currentTimeMillis() + EXPIRETIME;
    }
}